package com.example.demo.hutool.redis;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

import java.util.*;

@Slf4j
@Getter
@Setter
public class RedisTools {
    /**
     * ip地址
     */
    protected String ip;
    /**
     * 端口地址
     */
    protected Integer port;
    /**
     * 密码
     */
    protected String password;
    /**
     * 库
     */
    protected Integer instanceName;
    /**
     * redis版本   命令有区别
     */
    protected Double version;
    /**
     * 连接对象
     */
    public Jedis jedis;

    /**
     *
     */
    public String keys;

    /**
     * 是否需要同步过期时间
     */
    public Boolean ttl = true;
    /**
     * 类型
     */
    public String type;

    /**
     * 不需要匹配的keys
     */
    public Set<String> allKey;


    public static void main(String[] args) {
        RedisTools redisTools = new RedisTools();
        redisTools.setIp("47.114.168.226");
        redisTools.setPort(6379);
        redisTools.setPassword("123456");
        redisTools.setInstanceName(0);
        redisTools.init();
        redisTools.jedis.set("sxms", "geg");
        Set<String> keys1 = redisTools.keys(null);
        HashMap<String, Set<String>> initRedisMap = initRedisMap();
        keys1.forEach(s -> {
            String type = redisTools.jedis.type(s);
            initRedisMap.get(type).add(s);
            System.out.println("" + s + "--->" + type);
        });

        redisTools.close();
    }

    /**
     * 初始化redis类型集合map
     *
     * @return
     */
    private static HashMap<String, Set<String>> initRedisMap() {
        HashMap<String, Set<String>> initRedisMap = new HashMap<>();
        initRedisMap.put("list", new HashSet<>());
        initRedisMap.put("string", new HashSet<>());
        initRedisMap.put("zset", new HashSet<>());
        initRedisMap.put("hash", new HashSet<>());
        initRedisMap.put("set", new HashSet<>());
        return initRedisMap;
    }

    public void init() {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(2);
        config.setMaxIdle(2);
        config.setMinIdle(0);
        config.setMaxWaitMillis(3000L);
        config.setTestOnBorrow(true);
        config.setTestOnReturn(true);


        // 创建jedis对象
        Jedis jedis = new Jedis(ip, port);
        // 设置认证密码
        jedis.auth(password);
        // 指定数据库 默认是0
        jedis.select(instanceName);
        String pong = jedis.ping();
        log.info("连接成功{}", pong);
        //>= 2.6.0 可以执行lua脚本
        // Object info = jedis.eval("return redis.call('info')");
        this.jedis = jedis;
    }

    public void query() {
        String key = jedis.get(keys);




        Long ttl = getTTl(key);
    }


    /**
     * 获取当前需要查询类型下的keys
     *
     * @return
     */
    public Set<String> queryKey() {
        Set<String> keySet = keys(keys);
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            String type = jedis.type(next);
            if (!type.equals(this.type)) {
                iterator.remove();
            }
        }
        keySet.removeAll(allKey);
        return keySet;
    }

    public Set<String> keys(String keys) {
        try {
            //模糊匹配的KEY
            String VEHICLE_MATCH_KEY = "*";
            //结束点标识
            String SCAN_CURSOR_INDEX = String.valueOf(0);
            //一次扫描多少条数据
            Integer SCAN_CURSOR_COUNT = 10000;
            //创建扫描参数实体类
            ScanParams scanParams = new ScanParams();
            //设置模糊匹配的key
            scanParams.match(VEHICLE_MATCH_KEY);
            //设置分片扫描的数量
            scanParams.count(SCAN_CURSOR_COUNT);
            Set<String> delKeys = new HashSet<>();
            //游标索引开始和结束的索引值
            String cursor = SCAN_CURSOR_INDEX;
            //游标循环移动操作
            do {
                //开始扫描
                ScanResult<String> sr = jedis.scan(cursor, scanParams);
                //获取扫描返回结果
                List<String> keyResultList = sr.getResult();
                if (!CollectionUtils.isEmpty(keyResultList)) {
                    delKeys.addAll(keyResultList);
                }
                //更新游标位置
                cursor = sr.getCursor();
            } while (!SCAN_CURSOR_INDEX.equals(cursor));
//            //使用管道进行批量操作，减少redis连接
//            Pipeline pipeline = jedis.pipelined();
//            pipeline.sync();
            return delKeys;
        } catch (Exception e) {
            log.info("匹配失败 {},keys{}", e, keys);
            return jedis.keys(keys);
        }
    }

    /**
     * @param key
     * @return 当 key 不存在时，返回 -2 。 当 key 存在但没有设置剩余生存时间时，返回 -1 。 否则，以毫秒为单位，返回 key 的剩余生存时间。
     * 在 Redis 2.8 以前，当 key 不存在，或者 key 没有设置剩余生存时间时，命令都返回 -1 。
     */
    public Long getTTl(String key) {
        return jedis.ttl(key);
    }

    public void close() {
        if (jedis != null) jedis.close();
    }

}
